import {deepMerge, isPlainObject} from './util';
import {StrObj, Method} from '../types/';

function normalizeHeaderName (headers: StrObj, normalizedName: string): void {
  if (!headers) {
    return;
  }

  Object.keys(headers).forEach(name => {
    if (name !== normalizedName &&
      name.toUpperCase() === normalizedName.toUpperCase()) {
        headers[normalizedName] = headers[name];
        delete headers[name];
      }
  })
}

export function processHeaders (headers: StrObj, data: any): StrObj {
  normalizeHeaderName(headers, 'Content-Type');

  if (isPlainObject(data)) {
    if (headers && !headers['Content-Type']) {
      headers['Content-Type'] = 'application/json;charset=utf-8';
    }
  }
  return headers;
}

export function parseHeaders (headers: string): StrObj {
  const parsed: StrObj = Object.create(null);
  if (!headers) {
    return parsed;
  }

  headers.split(/\n|\r\n/).forEach(line => {
    if (!line) {
      return ;
    }

    const [key, val] = parseHanderLine(line);
    
    parsed[key] = val;
  })

  return parsed;
}

function parseHanderLine (line: string): [string, string] {
  const pattern = /(\w+):(.*)/;
  if (!pattern.test(line)) {
    throw new Error('Header format is wrong')
  }

  let key = RegExp.$1;
  let val = RegExp.$2;

  if(!key || !val) {
    throw new Error('Header format is wrong')
  }

  key = key.trim().toLowerCase();
  val = val.trim();

  return [key, val];
}

export function flattenHeaders (headers: any, method: Method): any {
  if (!headers) {
    return headers;
  }
  headers = deepMerge(headers.common || {}, headers[method] || {}, headers);

  const methodsToDelete = ['delete', 'get', 'head', 'options', 'post', 'put', 'patch', 'common'];

  methodsToDelete.forEach(method => {
    delete headers[method];
  })

  return headers;
}